package controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TimerTask;

import model.AppModel;
import model.Email;
import model.ModelException;

public class ConnectionMaintainer extends TimerTask {

	private String ip;
	private Integer port;
	private AppController appController;
	private AppModel appModel;

	public ConnectionMaintainer(AppController appController, AppModel model) {

		this.appController = appController;
		this.appModel = model;

		HashMap<String, String> serverProps = model.getServerProperties();
		ip = serverProps.get("ip");
		port = Integer.valueOf(serverProps.get("port"));
	}

	/**
	 * The scheduled task to be run after the timer refreshes
	 */
	@Override
	public void run() {
//
//		// First time socket running
//		if (model.serverSocket == null) {
//			connect();
//			return;
//		}
//
//		BufferedReader in = null;
//		try {
//			in = new BufferedReader(new InputStreamReader(
//					serverSocket.getInputStream()));
//		} catch (IOException e1) {
//			connect();
//		}
//
//		try {
//			if(in == null){
//				connect();
//			}
//			String line = in.readLine();
//			if (line.isEmpty() || line == null) {
//				connect();
//			}
//		} catch (IOException e1) {
//			connect();
//		}
//		sendRecieveEmails();
	}

	/**
	 * Tells the user that the connection has been lost and takes appropriate
	 * steps
	 */
	private void connectionLost() {
		setStatus(false);
		appModel.setConnected(false);
		appController.notify("error", "Not connected, trying to connect...");
	}

	/**
	 * Sets the network status in the view
	 * 
	 * @param c
	 */
	private void setStatus(boolean connected) {
		appController.getNavigationController().setNetworkStatus(connected);
	}

	/**
	 * Tries to connect the the server
	 * 
	 */
	private void connect() {
//		try {
//			serverSocket = new Socket(ip, port);
//			appController.notify("success", "Connected!");
//			setStatus(true);
//			sendTokenToServer();
//			//sendRecieveEmails();
//			appModel.setConnected(true);
//		} catch (UnknownHostException e) {
//			connectionLost();
//		} catch (IOException e) {
//			connectionLost();
//		}
	}

	/**
	 * This function creates a new theead that sends and recieves all the emails
	 * that exist in the outbox.
	 */
	public void sendRecieveEmails() {

		sendEmails();
		recieveEmails();
		appController.getNavigationController().refreshNavigationFolders(
				appModel.getCurrentFolderName());

	}

	/**
	 * Recieves all the emails and applies the filters
	 */
	private void recieveEmails() {
		// TODO Auto-generated method stub

	}

	/**
	 * Sends out all the emails in the inbox
	 */
	private void sendEmails() {

//		try {
//			OutputStream out = serverSocket.getOutputStream();
//			ObjectOutputStream objOut = new ObjectOutputStream(out);
//
//			List<Email> emailsToSend = new ArrayList<Email>();
//			for (Email email : appModel.getUser().getFolder("Outbox").getEmails()) {
//				System.out.println("mail to be sent: " + email.getId() + " Folder: " + email.getFolderId());
//				
//				emailsToSend.add(email);
//				email.setFolderId(appModel.getUser().getFolder("Sent").getId());
//				email.save();
//				
//				System.out.println("mail sent: " + email.getId() + " Folder: " + email.getFolderId());
//			}
//			objOut.writeObject(emailsToSend);
//			System.out.println(emailsToSend.size());
//			objOut.close();
//			out.close();
//		} catch (IOException e) {
//			System.out.print("IO in send emails");
//			e.printStackTrace();
//		} catch (ModelException e) {
//			System.out.print("Model in send emails");
//		}
	}
	
	/**
	 * Sends out all the emails in the inbox
	 */
	private void sendTokenToServer() {

//		try {
//			OutputStream out = serverSocket.getOutputStream();
//			ObjectOutputStream objOut = new ObjectOutputStream(out);
//			objOut.writeObject(appModel.getUser().getName());
//			objOut.close();
//			out.close();
//		} catch (IOException e) {
//			System.out.print("IO in send emails");
//			e.printStackTrace();
//		} 
	}

}
